package com.engine.budget.util;

import com.engine.budget.enums.Instruction;
import com.engine.budget.enums.VerifyMessage;
import com.weaver.formmodel.util.EncryptHelper;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import weaver.conn.RecordSet;
import weaver.file.Prop;
import weaver.general.TimeUtil;
import weaver.general.Util;
import weaver.hrm.User;
import weaver.integration.logging.Logger;
import weaver.integration.logging.LoggerFactory;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.*;

/**
 * @author DY
 * @date 2024/7/5 16:28
 * @description: 预算接口验证工具类
 * @version 1.0
 */
public class VerifyUtil {

    private static Logger logger = LoggerFactory.getLogger(VerifyUtil.class);

    public static  DecimalFormat decimalFormat = new DecimalFormat("0.00000");

    /**
     * @param: data otherMap rs
     * @return: java.util.Map<java.lang.String,java.lang.Object>
     * @description: 指令参数验证
    */
    public static Map<String, Object> verifyParams(Map<String, Object> data, Map<String, Object> otherMap,
                                     RecordSet rs) {

            //返回值明细细对象
            Map<String, Object> resdataMap = new HashMap();

            String logId = Util.null2String(otherMap.getOrDefault("logId", ""));

            try{
                resdataMap.put("budgetItem", data.getOrDefault("budgetItem",""));
                resdataMap.put("budgetAccount", data.getOrDefault("budgetAccount",""));
                resdataMap.put("org", data.getOrDefault("exeUnit",""));
                resdataMap.put("budgetPeriod", data.getOrDefault("budgetPeriod",""));
                resdataMap.put("amount", data.getOrDefault("amount",""));
                resdataMap.put("instruction", data.getOrDefault("instruction",""));
                resdataMap.put("occDocNo", data.getOrDefault("occDocNo",""));
                resdataMap.put("exeDocNo", data.getOrDefault("exeDocNo",""));
                resdataMap.put("budgetBalance", "");
                resdataMap.put("mattersBalance", "");
                resdataMap.put("projectBalance", "");
                resdataMap.put("occBalance", "");

                //指令
                String instruction = Util.null2String(data.getOrDefault("instruction",""));

                //被执行单据号 是否在单据控制策略表
                String whiteZxdjh = Util.null2String(otherMap.getOrDefault("whiteZxdjh", ""));
                if("1".equals(whiteZxdjh) || Instruction.IA.equals(instruction)) {
                    Map<String, Object> errMap = VerifyMessage.CKECKSUCCESS.fromMap();
                    errMap.put("status", 1);
                    errMap.put("data", resdataMap);
                    return  errMap;
                }
                //参数必填验证
                Map<String, String> emptyMap = VerifyUtil.paramMustVeifty(data);

                if(emptyMap.size() > 0) {
                    String emptyErrMessage = VerifyUtil.getEmptyErrMessage(emptyMap);
                    Map<String, Object> errMap = VerifyMessage.MUST_EMPTY.setErrorMessage(emptyErrMessage).fromMap();
                    errMap.put("status", -1);
                    errMap.put("data", resdataMap);
                    return errMap;
                }

                //2、通过入参的【预算项目】、【预算科目】、【执行单位】、【预算控制期】去“预算执行底表”匹配数据，
                //  只要有一条数据匹配不到，则整批数据全部失败。
                boolean checkYszxdbFlag = VerifyUtil.checkYszxdb(data, rs);
                if(!checkYszxdbFlag) {
                    String errMsg = "【budgetItem_预算项目】、【budgetAccount_预算科目】、" +
                            "【exeUnit_执行单位】、【budgetPeriod_预算期间】 未匹配到预算执行底表唯一数据";
                    Map<String, Object> errMap = VerifyMessage.YWYZ_ERR.setErrorMessage(errMsg).fromMap();
                    errMap.put("status", -1);
                    errMap.put("data", resdataMap);
                    return errMap;
                }

                //3、一批数据中任何一条的【预算控制期】跟“预算编制年度设置”中【预算执行】为“是”的年份不一样的，则整批数据全部失败。
                boolean checkYsbzndFlag = VerifyUtil.checkYsbznd(data, rs);
                if(!checkYsbzndFlag) {
                    String errMsg = " 【budgetPeriod_预算期间】未匹配到预算编制年度设置中合法数据";
                    Map<String, Object> errMap = VerifyMessage.YWYZ_ERR.setErrorMessage(errMsg).fromMap();
                    errMap.put("status", -1);
                    errMap.put("data", resdataMap);
                    return errMap;
                }

                //4、通过入参的【预算项目】、【预算科目】、【执行单位】、【预算控制期】去“预算执行底表”匹配【可用余额】，
                // 如果【传入金额】>【可用余额】，则整批数据全部失败。
                //可用余额
                String yszxdYe = VerifyUtil.getYszxdYe(data, rs);
                BigDecimal yszxdYeDecimal = new BigDecimal(yszxdYe);
                resdataMap.put("budgetBalance", decimalFormat.format(yszxdYeDecimal));
                //金额
                String amount = Util.null2String(data.getOrDefault("amount", ""));
                BigDecimal amountDecimal = new BigDecimal(amount);

                if(amountDecimal.compareTo(yszxdYeDecimal) > 0) {
                    String errMsg = "【amount_金额】不能大于预算执行底表【可用余额】";
                    Map<String, Object> errMap = VerifyMessage.YWYZ_ERR.setErrorMessage(errMsg).fromMap();
                    errMap.put("status", -1);
                    errMap.put("data", resdataMap);
                    return errMap;
                }

                //6、释放占用且执行、释放执行且占用、释放占用、仅项目释放占用且执行、仅项目释放执行且占用、仅项目释放占用，
                // 这些指令通过【被占用单据号】、【预算项目】、【预算科目】、【执行单位】、【预算控制期】去占用表中匹配数据，
                // 匹配不到则整批数据全部失败。
                Set<String> sfCommand = new HashSet<>();
                sfCommand.add(Instruction.SFZYQZX.getValue());
                sfCommand.add(Instruction.SFZXQZY.getValue());
                sfCommand.add(Instruction.SFZY.getValue());
                sfCommand.add(Instruction.XMSFZYQZX.getValue());
                sfCommand.add(Instruction.XMSFZXQZY.getValue());
                sfCommand.add(Instruction.XMSFZY.getValue());

                boolean checkYszybFlag = VerifyUtil.checkYszyb(sfCommand, data, rs);
                if(!checkYszybFlag) {
                    String errMsg = "【occDocNo_被占用单据号】【budgetItem_预算项目】、【budgetAccount_预算科目】、" +
                            "【exeUnit_执行单位】、【budgetPeriod_预算期间】 未匹配到占用表唯一数据";
                    Map<String, Object> errMap = VerifyMessage.YWYZ_ERR.setErrorMessage(errMsg).fromMap();
                    errMap.put("status", -1);
                    errMap.put("data", resdataMap);
                    return errMap;
                }

                //7、释放占用且执行、释放执行且占用、释放占用、仅项目释放占用且执行、仅项目释放执行且占用、仅项目释放占用，
                // 这些指令通过【被占用单据号】、【预算项目】、【预算科目】、【执行单位】、【预算控制期】去占用表中匹配【占用余额】，
                // 【传入金额】必须<=【占用余额】，否则整批数据全部失败。
                if(sfCommand.contains(instruction)) {
                    String yszybYe = VerifyUtil.getYszybYe(data, rs);
                    BigDecimal yszybYeDecimal = new BigDecimal(yszybYe);

                    resdataMap.put("occBalance", decimalFormat.format(yszybYeDecimal));

                    if(amountDecimal.compareTo(yszybYeDecimal) > 0) {
                        String errMsg = "【amount_金额】不能大于占用表【占用余额】";
                        Map<String, Object> errMap = VerifyMessage.YWYZ_ERR.setErrorMessage(errMsg).fromMap();
                        errMap.put("status", -1);
                        errMap.put("data", resdataMap);
                        return errMap;
                    }
                }


                //8、对于仅项目全周期执行的指令，通过【预算项目】、【预算科目】、【执行单位】
                // ，去匹配项目底表，匹配不到则整批数据全部失败。
                Set<String> xmCommand = new HashSet<>();
                xmCommand.add("XMZX");
                xmCommand.add("XMSFZX");
                xmCommand.add("XMZY");
                xmCommand.add("XMSFZY");
                xmCommand.add("XMSFZYQZX");
                xmCommand.add("XMSFZXQZY");

                boolean checkYsxmdbFlag = VerifyUtil.checkYsxmdb(xmCommand, data, rs);
                if(!checkYsxmdbFlag) {
                    String errMsg = "【budgetItem_预算项目】、【budgetAccount_预算科目】、" +
                            "【exeUnit_执行单位】 未匹配到项目底表唯一数据";
                    Map<String, Object> errMap = VerifyMessage.YWYZ_ERR.setErrorMessage(errMsg).fromMap();
                    errMap.put("status", -1);
                    errMap.put("data", resdataMap);
                    return errMap;
                }

                //9、对于仅项目全周期执行的指令，通过【预算项目】、【预算科目】、【执行单位】，
                // 去匹配项目底表，匹配到了用项目底表的【全周期剩余可执行金额】与【传入金额】比较，
                // 【全周期剩余可执行金额】必须>=【传入金额】，否则整批数据全部失败。
                //指令
                if(xmCommand.contains(instruction)) {
                    String ysxmdbYe = VerifyUtil.getYsxmdbYe(data, rs);
                    BigDecimal ysxmdbYeDecimal = new BigDecimal(ysxmdbYe);
                    resdataMap.put("projectBalance", decimalFormat.format(ysxmdbYeDecimal));

                    String ysSXdbYe = VerifyUtil.getYsSXdbYe(data, rs);
                    BigDecimal ysSXdbYeDecimal = new BigDecimal(ysSXdbYe);
                    resdataMap.put("mattersBalance", decimalFormat.format(ysSXdbYeDecimal));

                    if(amountDecimal.compareTo(ysxmdbYeDecimal) > 0) {
                        String errMsg = "【amount_金额】不能大于项目底表【全周期剩余可执行金额】";
                        Map<String, Object> errMap = VerifyMessage.YWYZ_ERR.setErrorMessage(errMsg).fromMap();
                        errMap.put("status", -1);
                        errMap.put("data", resdataMap);
                        return errMap;
                    }
                }

                //1、如果接口入参有一批参数，其中某条的经济事项在“经济事项&预算科目映射表”配置表中匹配不到预算科目的数据，
                // 则此条数据在执行记录表里标记失败，其余能匹配上数据的可以继续执行。
                boolean checkJJsxFlag = VerifyUtil.checkJJsx(data, rs);
                if(!checkJJsxFlag) {
                    String errMsg = "【economicEvent_经济事项在】【budgetAccount_科目编码】“经济事项&预算科目映射表”配置表中未匹配到预算科目";
                    Map<String, Object> errMap = VerifyMessage.YWYZ_ERR.setErrorMessage(errMsg).fromMap();
                    errMap.put("status", -11);
                    errMap.put("data", resdataMap);
                    return errMap;
                }

            }catch (Exception e) {
                logger.error("logId:"+logId+",入参检验异常errMsg:"+e.getMessage(), e);
                String errMsg = "入参检验异常,"+e.getMessage();
                Map<String, Object> errMap = VerifyMessage.YWYZ_ERR.setErrorMessage(errMsg).fromMap();
                errMap.put("status", -2);
                errMap.put("data", resdataMap);
                return errMap;
            }
            Map<String, Object> errMap = VerifyMessage.CKECKSUCCESS.fromMap();
            errMap.put("status", 1);
            errMap.put("data", resdataMap);

            return errMap;
    }

    /**
     * @param: data otherMap rs
     * @return: net.sf.json.JSONArray
     * @description: 电商平台接口参数转换为指令标准参数
    */
    public static JSONArray ecomParamsChange(JSONObject jsonData) {
        JSONArray resArray = new JSONArray();

        //当前日期
        String nowDate = TimeUtil.getCurrentDateString();
        //exeDocType	执行单据类型
        String exeDocType = Prop.getPropValue("businessbudgetpz", "dsptexeDocType");
        //occDocNo	被占用单据号
        String occDocNo = Prop.getPropValue("businessbudgetpz", "dsptoccDocNo");
        //economicEvent	经济事项
        String economicEvent = Prop.getPropValue("businessbudgetpz", "dspteconomicEvent");

        //sourceSystemCode	来源系统	sourceSystem	来源系统
        String sourceSystemCode = jsonData.getOrDefault("sourceSystemCode", "").toString();
        //docType	单据处理类型	instruction	指令	业务系统需要进行的操作类别代表
        String docType = jsonData.getOrDefault("docType", "").toString();
        if("KA".equals(docType)) {
            docType = "ZY";
        }else if("KB".equals(docType)) {
            docType = "SFZY";
        }
        //companyCode	报账公司	reimbursementCompany	报账公司	公司编码
        String companyCode = jsonData.getOrDefault("companyCode", "").toString();
        //departments	报账部门	reimbursementDept	报账部门
        String departments = jsonData.getOrDefault("departments", "").toString();
        //budgetPeriod	预算控制期	budgetPostingPeriod	预算控制期	yyyy-mm
        String budgetPostingPeriod = jsonData.getOrDefault("budgetPeriod", "").toString();
        String budgetPeriod = budgetPostingPeriod;
        if(budgetPeriod.length() > 4) {
            budgetPeriod = budgetPeriod.substring(0, 4);
        }
        //currencyCode	币种		/	预算币种编码，默认CNY
        String currencyCode = jsonData.getOrDefault("currencyCode", "").toString();

        JSONArray docs = jsonData.containsKey("doc") ? jsonData.getJSONArray("doc") : new JSONArray();
        int size = docs.size();
        for(Integer i = 0; i < size; i++) {
            JSONObject docObj = docs.getJSONObject(i);
            //docNumber	单据编号	exeDocNo	执行单据号
            String docNumber = docObj.getOrDefault("docNumber", "").toString();
            //producer	创建人	claimant	报账人
            String producer = docObj.getOrDefault("producer", "").toString();
            //remark	单据说明内容	remark	说明
            String remark = docObj.getOrDefault("remark", "").toString();

            JSONArray rows = docObj.containsKey("rows") ? docObj.getJSONArray("rows") : new JSONArray();
            int size1 = rows.size();
            for(int j = 0; j < size1; j++) {
                JSONObject newData = new JSONObject();

                newData.put("sourceSystem", sourceSystemCode);
                newData.put("instruction", docType);
                newData.put("reimbursementCompany", companyCode);
                newData.put("reimbursementDept", departments);
                newData.put("budgetPostingPeriod", budgetPostingPeriod);
                newData.put("budgetPeriod", budgetPeriod);
                newData.put("currencyCode", currencyCode);

                newData.put("exeDocNo", docNumber);
                newData.put("claimant", producer);
                newData.put("remark", remark);

                //exeDocType	执行单据类型
                newData.put("exeDocType", exeDocType);
                //occDocNo	被占用单据号
                newData.put("occDocNo", occDocNo);
                //executionDate	执行日期
                newData.put("executionDate", nowDate);
                //economicEvent	经济事项
                newData.put("economicEvent", economicEvent);

                JSONObject rowObj = rows.getJSONObject(j);
                //lineNumber	行编号		/
                // String lineNumber = rowObj.getOrDefault("lineNumber", "").toString();

                //budgetDepartmentCode	预算责任中心	exeUnit	执行单位
                String budgetDepartmentCode = rowObj.getOrDefault("budgetDepartmentCode", "").toString();
                newData.put("exeUnit",budgetDepartmentCode);

                //budgetAccountCode	预算科目	budgetAccount	预算科目
                String budgetAccountCode = rowObj.getOrDefault("budgetAccountCode", "").toString();
                newData.put("budgetAccount", budgetAccountCode);

                //budgetProjectCode	预算项目	budgetItem	预算项目
                String budgetProjectCode = rowObj.getOrDefault("budgetProjectCode", "").toString();
                newData.put("budgetItem", budgetProjectCode);

                //amount	金额	amount	金额
                String amount = rowObj.getOrDefault("amount", "").toString();
                newData.put("amount", amount);

                //departWorkCode	部门工作		/
               // String departWorkCode = rowObj.getOrDefault("departWorkCode", "").toString();
               // newData.put("departWorkCode", departWorkCode);

                //addValueTax	税额		/
               // String addValueTax = rowObj.getOrDefault("addValueTax", "").toString();

                resArray.add(newData);
            }
        }

        return resArray;
    }


    /**
     * @param: params
     * @return: java.lang.String 
     * @description: 固定签名认证参数
    */ 
    public static boolean verifyTicket(Map<String, Object> params) {
        try {
            JSONObject safetyObj = JSONObject.fromObject(params.get("safety"));
            //安全校验位
            String ticket = Util.null2String(safetyObj.getString("ticket"));
            //接口调用方账号
            String clientcode = Util.null2String(safetyObj.getString("clientcode"));
            //时间
            String time = Util.null2String(safetyObj.getString("time"));
            //操作单号
            String barcode = Util.null2String(safetyObj.getString("barcode"));
            //操作人账号
            String useraccount = Util.null2String(safetyObj.getString("useraccount"));

            if("".equals(ticket)) {
                return false;
            }
            //加密密码
            String safetypwd = Prop.getPropValue("businessbudgetpz", clientcode);

            //Time的值+clientcode的值+barcode的值+useraccount的值+密码
            String val = time + clientcode + barcode + useraccount + safetypwd;
            String yzticket = EncryptHelper.encodeMd5(val);

            if(ticket.equals(yzticket)) {
                return true;
            }
        }catch (Exception e) {
            return false;
        }
        return false;
    }

    public static User getUserByCode(String workcode, RecordSet rs) {
        String sql = "select id from hrmresource where workcode = ?";
        rs.executeQuery(sql, workcode);
        if(rs.next()) {
            Integer id = rs.getInt("id");
            User user = new User(id);
            return user;
        }

        return null;
    }

    /**
     * @param: params
     * @return: java.util.Map<java.lang.String,java.lang.String>
     * @description: 验证字段必填，返回未填写数据
    */
    public static Map<String, String> paramMustVeifty(Map<String, Object> params) {

        //String logId = Util.null2String(otherMap.get("logId"));

        String instruction = Util.null2String(params.getOrDefault("instruction", ""));

        //必填字段集合
        Map<String, String> mustParams = new HashMap<>();
        mustParams.put("budgetItem", "预算项目");
        mustParams.put("budgetAccount", "预算科目");
        mustParams.put("exeUnit", "执行单位");
        mustParams.put("budgetPeriod", "预算期间（年）");
        mustParams.put("amount", "金额");
        mustParams.put("instruction", "指令");
        mustParams.put("exeDocNo", "执行单据号");
        mustParams.put("budgetPostingPeriod", "预算控制期");
        mustParams.put("executionDate", "执行日期");
        mustParams.put("exeDocType", "执行单据类型");
        mustParams.put("sourceSystem", "来源系统");
        mustParams.put("reimbursementDept", "报账部门");
        mustParams.put("reimbursementCompany", "报账公司");
        //仅执行接口不验证必填字段
        if(!Instruction.JZX.equals(instruction)) {
            mustParams.put("claimant", "报账人");
            mustParams.put("remark", "说明");
            mustParams.put("economicEvent", "经济事项");
        }


        //占用指令集合
        Set<String> zyCommand = new HashSet<>();
        zyCommand.add(Instruction.SFZY.getValue());
        zyCommand.add(Instruction.SFZYQZX.getValue());
        zyCommand.add(Instruction.SFZXQZY.getValue());
        zyCommand.add(Instruction.ZY.getValue());

        HashMap<String, String> emptyMap = new HashMap<>();

        for (Map.Entry<String, String> entry : mustParams.entrySet()) {
            String key = entry.getKey();
            String value = entry.getValue()+"不能为空";

            if("".equals(Util.null2String(params.getOrDefault(key, "")))) {
                emptyMap.put(key, value);
                continue;
            }

            //被占用单据号
            //非必传，下列情况必传：
                //释放占用且执行,释放执行且占用、释放占用（必传）
                //占用（特殊情况必传）
            if("instruction".equals(key) && zyCommand.contains(value)) {
                if ("".equals(Util.null2String(params.getOrDefault("occDocNo", "")))) {
                    emptyMap.put("occDocNo", "指令为"+value+"时，被占用单据号不能为空");
                }
            }else if("amount".contains(key)) {
                double amount = Util.getDoubleValue(params.getOrDefault("amount", "").toString(), -1);
                if(amount < 1) {
                    emptyMap.put("amount", "金额非法");
                }
            }
        }

//        //报账人
//        String claimant = Util.null2String(params.getOrDefault("claimant", ""));
//        String sql = "select id from hrmresouce where workcode = ?";
//        boolean sqlFlag = rs.executeQuery(sql, claimant);
//        logger.info("logId:"+logId+"【claimant_报账人】字段转换sql:"+sql+",sqlFlag:"+sqlFlag+",workcode:"+claimant);
//        if(sqlFlag && rs.next()) {
//            params.put("claimant_id", Util.null2String(rs.getString("id")));
//        }else {
//            emptyMap.put("claimant", "未查询到对应人员id");
//        }
//
//        //报账部门
//        String reimbursementDept = Util.null2String(params.getOrDefault("reimbursementDept", ""));
//        sql = "select id from hrmdepartment where departmentcode = ?";
//        sqlFlag = rs.executeQuery(sql, reimbursementDept);
//        logger.info("logId:"+logId+"【reimbursementDept_报账部门】字段转换sql:"+sql+",sqlFlag:"+sqlFlag
//                +",departmentcode:"+reimbursementDept);
//        if(sqlFlag && rs.next()) {
//            params.put("reimbursementDept_id", Util.null2String(rs.getString("id")));
//        }else {
//            emptyMap.put("reimbursementDept", "未查询到对应部门id");
//        }
//
//        //报账公司
//        String reimbursementCompany = Util.null2String(params.getOrDefault("reimbursementCompany", ""));
//        sql = "select id from hrmsubcompany where subcompanycode = ?";
//        sqlFlag = rs.executeQuery(sql, reimbursementCompany);
//        logger.info("logId:"+logId+"【reimbursementCompany_报账公司】字段转换sql:"+sql+",sqlFlag:"+sqlFlag
//                +",subcompanycode:"+reimbursementCompany);
//        if(sqlFlag && rs.next()) {
//            params.put("reimbursementCompany_id", Util.null2String(rs.getString("id")));
//        }else {
//            emptyMap.put("reimbursementCompany", "未查询到对应公司id");
//        }


        return emptyMap;
    }

    /**
     * @param: list
     * @return: java.lang.String
     * @description: 拼接所有必填字段未填错误信息
    */
    public static String getEmptyErrMessage(Map<String, String> map) {

        StringJoiner resJoiner = new StringJoiner(",");
        for (Map.Entry<String, String> entry : map.entrySet()) {
            resJoiner.add(entry.getKey()+"_"+entry.getValue());
        }

        return resJoiner.toString();
    }

    /**
     * @param: params,rs
     * @return: boolean
     * @description: 检查【预算期间】跟“预算编制年度设置”中【预算执行】是否为“是”
    */
    public static boolean checkYsbznd(Map<String, Object> params, RecordSet rs) {

        //预算期间
        String budgetPeriod = Util.null2String(params.getOrDefault("budgetPeriod", ""));

        String sql = "select count(1) num from uf_ysbzndsz where ysnd = ? and yszh = '0'";
        boolean b = rs.executeQuery(sql, budgetPeriod);
        if(b && rs.next()) {
            int num = Util.getIntValue(rs.getString("num"), -1);
            if(num > 0) {
                return true;
            }
        }
        return false;
    }

    /**
     * @param: params, rs
     * @return: boolean
     * @description: 入参匹配预算执行底表数据
     */
    public static boolean checkYszxdb(Map<String, Object> params, RecordSet rs) {

        //预算项目
        String budgetItem = Util.null2String(params.getOrDefault("budgetItem",""));
        //预算科目
        String budgetAccount = Util.null2String(params.getOrDefault("budgetAccount",""));
        //执行单位
        String exeUnit = Util.null2String(params.getOrDefault("exeUnit",""));
        //预算区间 对应表单预算年度字段
        String budgetPeriod = Util.null2String(params.getOrDefault("budgetPeriod", ""));

        String sql = "select count(1) num from uf_yszxdb where ysxm = ? and yskm = ? and zhdw = ? and  ysnd = ? ";
        boolean b = rs.executeQuery(sql, budgetItem, budgetAccount, exeUnit, budgetPeriod);
        if(b && rs.next()) {
            int num = Util.getIntValue(rs.getString("num"), -1);
            if(num == 1) {
                return true;
            }
        }
        return false;
    }

    /**
     * @param: params, rs
     * @return: boolean
     * @description: 获取入参匹配预算执行底表余额
     */
    public static String getYszxdYe(Map<String, Object> params, RecordSet rs) {

        //预算项目
        String budgetItem = Util.null2String(params.getOrDefault("budgetItem",""));
        //预算科目
        String budgetAccount = Util.null2String(params.getOrDefault("budgetAccount",""));
        //执行单位
        String exeUnit = Util.null2String(params.getOrDefault("exeUnit",""));
        //预算区间  对应表单预算年度字段
        String budgetPeriod = Util.null2String(params.getOrDefault("budgetPeriod", ""));

        String sql = "select ysye from uf_yszxdb where ysxm = ? and yskm = ? and zhdw = ? and  ysnd = ? ";
        boolean b = rs.executeQuery(sql, budgetItem, budgetAccount, exeUnit, budgetPeriod);
        if(b && rs.next()) {
            String ysye = Util.getDoubleValue(rs.getString("ysye"), 0)+"";
            return ysye;
        }
        return "0";
    }

    /**
     * @param: params, rs
     * @return: boolean
     * @description: 入参匹配预算占用表数据
     */
    public static boolean checkYszyb(Set<String> sfCommand, Map<String, Object> params, RecordSet rs) {

        //指令
        String instruction = Util.null2String(params.getOrDefault("instruction",""));

        if(!sfCommand.contains(instruction)) {
            return true;
        }

        //被占用单据号
        String occDocNo = Util.null2String(params.getOrDefault("occDocNo",""));

        //预算项目
        String budgetItem = Util.null2String(params.getOrDefault("budgetItem",""));
        //预算科目
        String budgetAccount = Util.null2String(params.getOrDefault("budgetAccount",""));
        //执行单位
        String exeUnit = Util.null2String(params.getOrDefault("exeUnit",""));
        //_预算期间 对应表单预算年度字段
        String budgetPeriod = Util.null2String(params.getOrDefault("budgetPeriod", ""));

        String sql = "select count(1) num from uf_yszyb_dt1 where dh = ? and ysxm = ? and yskm = ? and zhdw = ? and  ysnd = ? ";
        boolean b = rs.executeQuery(sql, occDocNo, budgetItem, budgetAccount, exeUnit, budgetPeriod);
        if(b && rs.next()) {
            int num = Util.getIntValue(rs.getString("num"), -1);
            if(num == 1) {
                return true;
            }
        }
        return false;
    }

    /**
     * @param: params, rs
     * @return: boolean
     * @description: 获取入参匹配预算占用表余额
     */
    public static String getYszybYe(Map<String, Object> params, RecordSet rs) {
        //被占用单据号
        String occDocNo = Util.null2String(params.getOrDefault("occDocNo",""));
        //预算项目
        String budgetItem = Util.null2String(params.getOrDefault("budgetItem",""));
        //预算科目
        String budgetAccount = Util.null2String(params.getOrDefault("budgetAccount",""));
        //执行单位
        String exeUnit = Util.null2String(params.getOrDefault("exeUnit",""));
        //预算期间  对应表单预算年度字段
        String budgetPeriod = Util.null2String(params.getOrDefault("budgetPeriod", ""));
        //金额
        String amount = Util.null2String(params.getOrDefault("amount",""));
        BigDecimal amountDecimal = new BigDecimal(amount);

        String sql = "select zyye from uf_yszyb_dt1 where dh = ? and ysxm = ? and yskm = ? and zhdw = ? and  ysnd = ? ";
        boolean b = rs.executeQuery(sql, occDocNo, budgetItem, budgetAccount, exeUnit, budgetPeriod);
        if(b && rs.next()) {
            String zyye = Util.getDoubleValue(rs.getString("zyye"), 0)+"";
            return zyye;
        }
        return "0";
    }


    /**
     * @param: params, rs
     * @return: boolean
     * @description: 入参匹配预算项目底表数据
     */
    public static boolean checkYsxmdb(Set<String> xmCommand, Map<String, Object> params, RecordSet rs) {

        //指令
        String instruction = Util.null2String(params.getOrDefault("instruction",""));
        if(!xmCommand.contains(instruction)) {
            return true;
        }

        //预算项目
        String budgetItem = Util.null2String(params.getOrDefault("budgetItem",""));
        //预算科目
        String budgetAccount = Util.null2String(params.getOrDefault("budgetAccount",""));
        //执行单位
        String exeUnit = Util.null2String(params.getOrDefault("exeUnit",""));

        String sql = "select count(1) num from uf_ysxmdb t1 " +
                " left join uf_ysxmdb_dt2 t2 on t1.id = t2.mainid where t1.xmbm = ? and t2.yskm = ? and t1.zhdw = ? ";
        boolean b = rs.executeQuery(sql, budgetItem, budgetAccount, exeUnit);
        if(b && rs.next()) {
            int num = Util.getIntValue(rs.getString("num"), -1);
            if(num == 1) {
                return true;
            }
        }
        return false;
    }

    /**
     * @param: params, rs
     * @return: boolean
     * @description: 通过入参匹配预算项目底表获取余额
     */
    public static String getYsxmdbYe(Map<String, Object> params, RecordSet rs) {

        //预算项目
        String budgetItem = Util.null2String(params.getOrDefault("budgetItem",""));
        //预算科目
        String budgetAccount = Util.null2String(params.getOrDefault("budgetAccount",""));
        //执行单位
        String exeUnit = Util.null2String(params.getOrDefault("exeUnit",""));

        String sql = "select t2.qzqsykzhje from uf_ysxmdb t1 " +
                " left join uf_ysxmdb_dt2 t2 on t1.id = t2.mainid where t1.xmbm = ? and t2.yskm = ? and t1.zhdw = ? ";
        boolean b = rs.executeQuery(sql, budgetItem, budgetAccount, exeUnit);
        if(b && rs.next()) {
            String qzqsykzhje = Util.getDoubleValue(rs.getString("qzqsykzhje"), 0)+"";
            return qzqsykzhje;
        }
        return "0";
    }

    /**
     * @param: params, rs
     * @return: boolean
     * @description: 通过入参匹配预算事项底表获取余额
     */
    public static String getYsSXdbYe(Map<String, Object> params, RecordSet rs) {

        //预算项目
        String budgetItem = Util.null2String(params.getOrDefault("budgetItem",""));
        //预算科目
        String budgetAccount = Util.null2String(params.getOrDefault("budgetAccount",""));
        //执行单位
        String exeUnit = Util.null2String(params.getOrDefault("exeUnit",""));

        String sql = "select t1.yssx yssx  from uf_ysxmdb t1 " +
                " left join uf_ysxmdb_dt2 t2 on t1.id = t2.mainid where t1.xmbm = ? and t2.yskm = ? and t1.zhdw = ? ";
        boolean b = rs.executeQuery(sql, budgetItem, budgetAccount, exeUnit);
        if(!b) {
            return "0";
        }
        String yssx = Util.null2String(rs.getString("yssx"));
        sql = "select t1.qzqsyklxje from uf_yssxdb t " +
                " inner join uf_yssxdb_dt1 t1 on t.id = t1.mainid " +
                " where t.id = ? and t1.yskm = ? and t1.ysnd = ? ";

        b = rs.executeQuery(sql, yssx, budgetAccount, exeUnit);
        if(b && rs.next()) {
            String qzqsyklxje = Util.getDoubleValue(rs.getString("qzqsyklxje"), 0)+"";
            return qzqsyklxje;
        }
        return "0";
    }


    /**
     * @param: params rs
     * @return: boolean
     * @description: 经济事项在“经济事项&预算科目映射表”配置表中匹配预算科目的数据
    */
    public static boolean checkJJsx(Map<String, Object> params, RecordSet rs) {

        //经济事项
        String economicEvent = Util.null2String(params.getOrDefault("economicEvent", ""));
        //预算科目
        String budgetAccount = Util.null2String(params.getOrDefault("budgetAccount",""));

        String sql = "select count(1) num from uf_jjsxyskmysb where jjsxbm = ? and kmbm = ? ";
        boolean b = rs.executeQuery(sql, economicEvent, budgetAccount);
        if(b && rs.next()) {
            int num = Util.getIntValue(rs.getString("num"), -1);
            if(num > 0) {
                return true;
            }
        }

        return false;
    }

    /**
     * @param: params
     * @return: boolean
     * @description: 检查指令是否存在
    */
    public static boolean checkInstruction(Map<String, Object> params) {

        //指令
        String instruction = Util.null2String(params.getOrDefault("instruction", ""));

        boolean b = Instruction.hasInstance(instruction);

        return b;
    }

}
